#include <string>
using namespace std;

#define EXPAND_VALUE 8

class Order;
class Customer;
class RestaurantSystem;
class CustomerDataBase;
class OrderDataBase;

enum ErrorType{
	OK,
	GENERAL_ERROR,
	NOT_FOUND_ERROR,
	MEMORY_ERROR,
	ALREADY_EXIST_ERROR,
};

enum DrinkType {
	NODRINK,
	COLA,
	SPRITE
};
enum FirstType {
	NOFIRST,
	SOUP,
	HUMMUS
};
enum MainType {
	NOMAIN,
	STEAK,
	HAMBURGER
};
enum DesertType {
	NODESERT,
	CAKE,
	BAMBA
};

class Customer{
public:
	Customer(const char * name);
	~Customer();

	ErrorType order(DrinkType drink, FirstType first, MainType main, DesertType desert);
	ErrorType getOrder(DrinkType &drink, FirstType &first, MainType &main, DesertType &desert) const;
	ErrorType getOrder(Order **order) const;
	const char *getName() const;
private:
	const char *name;
	Order *orderInstance;
};

class Order{
public:
	Order(Customer *customer);
	~Order();
	ErrorType setOrder(DrinkType drink, FirstType first, MainType main, DesertType desert);
	ErrorType getOrder(DrinkType &drink, FirstType &first, MainType &main, DesertType &desert) const;
private:
	Customer *customer;
	DrinkType drink;
	FirstType first;
	MainType main;
	DesertType desert;
};

class CustomerDataBase {
public:
	CustomerDataBase();
	~CustomerDataBase();
	ErrorType addCustomer(Customer& customer);
	ErrorType removeCustomer(Customer& customer);
	ErrorType getCustomer(const char *name, Customer **customer) const;
private:
	ErrorType expandDataBase();
	ErrorType reduceDataBase();
	ErrorType shiftLeft(int i);
	int nofCustomers;
	int arraySize;
	Customer **customers;
};

class OrderDataBase {
public:
	OrderDataBase();
	~OrderDataBase();
	ErrorType addOrder(Order& order);
	ErrorType removeOrder(Order& order);
private:
	ErrorType expandDataBase();
	ErrorType reduceDataBase();
	ErrorType shiftLeft(int i);
	int nofOrders;
	int arraySize;
	Order **orders;
};


class RestaurantSystem {
public:
	RestaurantSystem();
	~RestaurantSystem();
	ErrorType addCustomer(const char *name);
	ErrorType deleteCustomer(const char *name);
	ErrorType order(const char *name, DrinkType drink, FirstType first, MainType main, DesertType desert);
	ErrorType getOrder(const char *name, DrinkType &drink, FirstType &first, MainType &main, DesertType &desert) const;
private:
	ErrorType getCustomer(const char *name, Customer **customer) const;
	CustomerDataBase *customers;
	OrderDataBase *orders;
};
